﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using JBeamLibrary.Types;
using JBeamLibrary.VehicleParts;
using JBeamLibrary.VehicleParts.Elements;
using Newtonsoft.Json.Linq;

namespace JBeamLibrary.Tools
{
    public static class JTokenExtension
    {
        public static T FromJBeam<T>(this JToken token)
        {
            return (T)FromJBeam(token, typeof(T));
        }

        public static object FromJBeam(this JToken token, Type outputType)
        {
            if (token is JValue)
            {
                var jval = token as JValue;
                if (outputType == typeof(byte))
                    return jval.ToByte();
                if (outputType == typeof(int))
                    return jval.ToInt();
                if (outputType == typeof(float))
                    return jval.ToFloat();
                if (outputType == typeof(long))
                    return jval.ToLong();
                if (outputType == typeof(bool))
                    return jval.ToBool();
                if (outputType == typeof(string))
                    return jval.ToString(CultureInfo.CurrentUICulture);
                if (outputType == typeof(BeamType))
                    return BeamTypes.GetEnumValue(jval.ToString(CultureInfo.InvariantCulture));
                if (outputType == typeof(NodeMaterial))
                    return NodeMaterials.GetEnumValue(jval.ToString(CultureInfo.InvariantCulture));
                if (outputType.IsEnum)
                    return Enum.Parse(outputType, jval.ToString(CultureInfo.InvariantCulture));
            }
            else if (token is JArray)
            {
                var jarr = token as JArray;
                if (outputType == typeof(AxleBeams))
                    return new AxleBeams(jarr.Values<string>());
            }
            else if (token is JObject)
            {
                var jobj = token as JObject;
                if (outputType == typeof(Float3))
                    return new Float3(
                        (float)jobj.Property("x").Value.FromJBeam(typeof(float)),
                        (float)jobj.Property("y").Value.FromJBeam(typeof(float)),
                        (float)jobj.Property("z").Value.FromJBeam(typeof(float))
                    );
                if (outputType == typeof (Color))
                    return new Color(
                        (byte)jobj.Property("a").Value.FromJBeam(typeof(byte)),
                        (byte)jobj.Property("r").Value.FromJBeam(typeof(byte)),
                        (byte)jobj.Property("g").Value.FromJBeam(typeof(byte)),
                        (byte)jobj.Property("b").Value.FromJBeam(typeof(byte))
                    );
            }
            return null;
        }
    }
}
